'''
Created on 2010/07/08

@author: saburo
'''
import binascii
from pyrfid.Util.Util import Util

class Decompactor(object):
    
    
    DECOMPACT_APPLICATION_DEFINED = 0
    DECOMPACT_UTF_8 = 7
    DECOMPACT_INT = 1
    DECOMPACT_NUMBER = 2
    DECOMPACT_BIT5 = 3
    DECOMPACT_BIT6 = 4
    DECOMPACT_BIT7 = 5
    DECOMPACT_NO = 6
    
    @classmethod
    def decompactObject(cls, compaction_type, object_value):
        """
        compaction_type -- a int data
        object_value -- a string data
        """
        object_value = object_value.upper()
        decompacted_object_value = ""
        if compaction_type == cls.DECOMPACT_APPLICATION_DEFINED:
            decompacted_object_value = object_value
        elif compaction_type == cls.DECOMPACT_UTF_8:
            decompacted_object_value =  cls.utf8Decompact(object_value)
        elif compaction_type == cls.DECOMPACT_INT:
            decompacted_object_value = cls.intDecompact(object_value)
        elif compaction_type == cls.DECOMPACT_NUMBER:
            decompacted_object_value = cls.numericDecompact(object_value)
        elif compaction_type == cls.DECOMPACT_BIT5:
            decompacted_object_value = cls.bit5Decompact(object_value)
        elif compaction_type == cls.DECOMPACT_BIT6:
            decompacted_object_value = cls.bit6Decompact(object_value)
        elif compaction_type == cls.DECOMPACT_BIT7:
            decompacted_object_value = cls.bit7Decompact(object_value)
        elif compaction_type == cls.DECOMPACT_NO:
            decompacted_object_value = object_value
        else:
            raise "UNDEFINED COMPACTED TYPE"
        
        return decompacted_object_value
    
    ################################################################################
    #     DECOMPACTIN
    ################################################################################
    @staticmethod
    def intDecompact(strHex):
        """       """
        hexInt = str()
        int = eval('0x' + strHex)
        for n in str(int):
            hexInt += binascii.b2a_hex(n)
        return hexInt
    
    @staticmethod
    def numericDecompact(strHex):
        """        """
        hexNum = str()
        if strHex[-1] == 'F':
            num = strHex[:-1]
        else:
            num = strHex
        for n in num:
            hexNum += binascii.b2a_hex(n)
        return hexNum
    
    @staticmethod
    def bit5Decompact(strHex):
        """        """
        strBit = str()
        hexChar = str() 

        for c in strHex:
            strBit += Util.h2b.get(c)
        pad = len(strBit) % 5
        if pad == 0:
            if strBit[-5:] == '00000':
                strBit = strBit[:-5]
        else:
            if pad < 3 and strBit[-pad-5:] == '0' * (pad + 5):
                pad = pad + 5
                strBit = strBit[:-pad]
        for i in range(len(strBit) / 5):
            temp = '010' + strBit[:5]
            hexChar += Util.b2h.get(temp[:4]) + Util.b2h.get(temp[4:])
            strBit = strBit[5:]
        return hexChar
    
    @staticmethod
    def bit6Decompact(strHex):
        """        """
        strBit = str()
        hexChar = str()

        for c in strHex:
            strBit += Util.h2b.get(c)
        if len(strBit)%6 == 0:
            if strBit[-6:] == '100000':
                strBit = strBit[:-6]
        else:
            pad = len(strBit) % 6
            strBit = strBit[:-pad]
        for i in range(len(strBit) / 6):
            temp = strBit[:6]
            if temp[0] == '0':
                temp = '01' + temp
            else:
                temp = '00' + temp
            hexChar += Util.b2h.get(temp[:4]) + Util.b2h.get(temp[4:])
            strBit = strBit[6:]
        return hexChar
    
    @staticmethod
    def bit7Decompact(strHex):
        """        """
        strBit = str()
        hexChar = str()
        
        for c in strHex:
            strBit += Util.h2b.get(c)
        pad = len(strBit) % 7
        if pad == 0:
            if strBit[-7:] == '1111111':
                strBit = strBit[:-7]
        else:
            strBit = strBit[:-pad]
        for i in range(len(strBit) / 7):
            temp = '0' + strBit[:7]
            hexChar += Util.b2h.get(temp[:4]) + Util.b2h.get(temp[4:])
            strBit = strBit[7:]
        return hexChar   
    
    @staticmethod
    def octetDecompact(strHex):
        return strHex
    
    @staticmethod
    def utf8Decompact(strHex):
        return strHex
    
    